package com.zqc.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zqc.common.lang.Const;
import com.zqc.common.lang.Result;
import com.zqc.entity.SysRole;
import com.zqc.entity.SysRoleMenu;
import com.zqc.entity.SysUserRole;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zqc
 * @since 2023-03-07
 */
@RestController
@RequestMapping("/sys/roles")
public class SysRoleController extends BaseController {

    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result info(@PathVariable(name = "id") Long roleId) {
        SysRole role = sysRoleService.getById(roleId);
        // 获取menuIds
        List<SysRoleMenu> roleMenuList = roleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        List<Long> menuIds = roleMenuList.stream().map(m -> m.getMenuId()).collect(Collectors.toList());

        role.setMenuIds(menuIds);
        return Result.succ(role);
    }

    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result list(String name) {

        Page<SysRole> page = sysRoleService.page(getPage(), new LambdaQueryWrapper<SysRole>()
                .like(name != null, SysRole::getName, name));

        return Result.succ(page);
    }


    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result save(@Validated @RequestBody SysRole role) {
        // 设置数据
        role.setCreated(LocalDateTime.now());
        role.setStatus(Const.ROLE_STATUS_ON);
        // 保存
        sysRoleService.save(role);

        return Result.succ(role);
    }

    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public Result update(@Validated @RequestBody SysRole role) {
        role.setUpdated(LocalDateTime.now());
        sysRoleService.updateById(role);
        // 清除与该角色相关的用户权限缓存
        sysUserService.clearUserAuthorityInfoByRoleId(role.getId());

        return Result.succ(role);
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @Transactional // 开启事务
    @PostMapping("/delete/{ids}")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result delete(@PathVariable(name = "ids") Long[] ids) {
        sysRoleService.removeByIds(Arrays.asList(ids));

        // 清空 中间表 数据
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", ids));
        userRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", ids));

        // 清除与该角色相关的用户权限缓存
        Arrays.stream(ids).forEach(id -> {
            sysUserService.clearUserAuthorityInfoByRoleId(id);
        });

        return Result.succ("删除成功");
    }

    /**
     * 角色分配操作菜单的权限
     *
     * @param roleId
     * @param menuIds
     * @return
     */
    @Transactional
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public Result prem(@PathVariable(name = "roleId") Long roleId, @RequestBody Long[] menuIds) {
        List<SysRoleMenu> roleMenus = new ArrayList<>();
        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);

            roleMenus.add(sysRoleMenu);
        });

        // 先删除数据库的数据在保存
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
        roleMenuService.saveBatch(roleMenus);

        // 清空与用户相关的权限缓存
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);

        return Result.succ("权限分配操作成功");
    }

}
